package com.notary.tx_live_plugin.util;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;

import androidx.fragment.app.FragmentActivity;

import com.notary.tx_live_plugin.widget.TxLivePushView;

import java.lang.ref.WeakReference;
import java.util.Map;

import io.flutter.plugin.common.PluginRegistry;

/**
 * 推流管理，摄像机权限处理
 */
public class PushManager implements PluginRegistry.RequestPermissionsResultListener {

    private TxLivePushView mTxLivePushView;
    private OnPushCallback mOnPushCallback;
    private WeakReference<Activity> mActivity;

    public static PushManager getInstance(){
        return PushManagerHolder.instance;
    }

    private static final class PushManagerHolder {
        private static final PushManager instance = new PushManager();
    }

    private PushManager(){}

    /**
     * 设置推流view
     */
    public void setPushView(TxLivePushView txLivePushView) {
        this.mTxLivePushView = txLivePushView;
        if (txLivePushView != null) {
            txLivePushView.setOnPushCallback(PushManager.this::callback);
        }
    }

    public void setActivity(Activity activity) {
        if (mActivity != null) mActivity.clear();
        if (activity != null) this.mActivity = new WeakReference<>(activity);
    }

    public void setOnPushCallback(OnPushCallback onPushCallback) {
        this.mOnPushCallback = onPushCallback;
    }

    /**
     * 清除变量
     */
    public void clear(){
        setPushView(null);
        //setActivity(null);//交由生命周期处理
        setOnPushCallback(null);
    }

    @Override
    public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == TxLivePluginConstant.REQUEST_TAKE_PUSH) {
            if (TxLiveUtils.isPermissionOK(permissions, grantResults)) {
                if (mTxLivePushView != null) mTxLivePushView.initPushView();
                return true;
            }else{
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < permissions.length; i++) {
                    sb.append(permissions[i]).append("  ").append(grantResults[i] != PackageManager.PERMISSION_DENIED).append(",");
                }
                callback(TxConstant.PushMethod.Back.error, "permission deny:"+(sb.length()>0?sb.substring(0,sb.length()-1):sb));
                TxLogger.d("Permission","requestCode1 permissionOK fail:"+sb);
            }
        }
        return false;
    }

    /**
     * 添加推流控件前，请求权限
     */
    public void requestPermissionForPush() {
        if (mActivity == null || mActivity.get() == null) {
            TxLogger.d("---------- permission failed mActivity is null",mActivity == null);
            if (mTxLivePushView != null) mTxLivePushView.initPushView();
            return;
        }
        Activity activity = mActivity.get();
        //直播录像
        TxLiveUtils.requestPermission(activity instanceof FragmentActivity ? activity : activity, TxLivePluginConstant.REQUEST_TAKE_PUSH
                , Manifest.permission.CAMERA
                , Manifest.permission.RECORD_AUDIO
//                , Manifest.permission.ACCESS_COARSE_LOCATION
//                , Manifest.permission.ACCESS_FINE_LOCATION
                , Manifest.permission.WRITE_EXTERNAL_STORAGE
                , Manifest.permission.READ_EXTERNAL_STORAGE
                );
    }

    public void onResume() {
        if (checkPushView(TxConstant.PushMethod.onResume)) {
            return;
        }
        mTxLivePushView.onResume();
    }

    public void onPause() {
        if (checkPushView(TxConstant.PushMethod.onPause)) {
            return;
        }
        mTxLivePushView.onPause();
    }

    public void onDestroy() {
        if (checkPushView(TxConstant.PushMethod.onDestroy)) {
            return;
        }
        mTxLivePushView.onDestroy();
    }

    public boolean isFlashLightOpen() {
        if (checkPushView(TxConstant.PushMethod.isFlashLightOpen)) {
            return false;
        }
        return mTxLivePushView.isFlashLightOpen();
    }

    public boolean isPushRecording() {
        if (checkPushView(TxConstant.PushMethod.isPushRecording)) {
            return false;
        }
        return mTxLivePushView.isPushing();
    }

    public boolean isFontCamera() {
        if (checkPushView(TxConstant.PushMethod.isFontCamera)) {
            return false;
        }
        return mTxLivePushView.isFontCamera();
    }

    public void turnOnFlashLight() {
        if (checkPushView(TxConstant.PushMethod.turnOnFlashLight)) {
            return;
        }
        mTxLivePushView.turnOnFlashLight();
    }

    public void switchCamera() {
        if (checkPushView(TxConstant.PushMethod.switchCamera)) {
            return;
        }
        mTxLivePushView.switchCamera();
    }

    public void stopLivePush() {
        if (checkPushView(TxConstant.PushMethod.stopLivePush)) {
            return;
        }
        mTxLivePushView.stopPush();
    }

    /**
     * 开始推流
     *
     * @param data map参数，key包含 url、serverTime
     */
    public boolean startLivePush(Object data) {
        if (checkPushView(TxConstant.PushMethod.startLivePush)) {
            return false;
        }
        //推流url
        String url = null;
        //分辨率-标志、高清，默认false为高清
        Boolean isBitrateStandard = false;
        //服务端时间，用于视频设置时间戳
        Long time = null;
        if (data instanceof Map) {
            Map<String, Object> d = (Map<String, Object>) data;
            url = (String) d.get(TxConstant.PushMethod.Key.url);
            time = (Long) d.get(TxConstant.PushMethod.Key.serverTime);
            isBitrateStandard = (Boolean) d.get(TxConstant.PushMethod.Key.isBitrateStandard);
        }
        if (url == null || time == null) {
            callback(TxConstant.PushMethod.Back.error, "method startLivePush need param,url " + url + " serverTime " + time + ",data " + data.toString());
            return false;
        }
        return mTxLivePushView.startLivePush(url, time, isBitrateStandard != null && isBitrateStandard);
    }

    private void callback(String method, Object data) {
        if (mOnPushCallback != null) {
            mOnPushCallback.callback(method, data);
        }
    }

    /**
     * 确认推流控件是否为空
     */
    private boolean checkPushView(String methodName) {
        if (mTxLivePushView == null) {
            callback(TxConstant.PushMethod.Back.error, "push view is empty for method " + methodName);
            return true;
        }
        return false;
    }

    /**
     * 推流功能，对flutter的回调
     */
    public interface OnPushCallback {
        void callback(String methodName, Object data);
    }
}
